/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package utils;

import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;

/**
 *
 * @author may1
 */
public class BusyIndicator extends JComponent implements ActionListener {

    private int frame = -1;  // animation frame index
    private final int nBars = 8;
    private final float barWidth = 6;
    private final float outerRadius = 28;
    private final float innerRadius = 12;
    private final int trailLength = 4;
    private final float barGray = 200f;  // shade of gray, 0-255
    private final Timer timer = new Timer(65, this); // 65ms = animation rate

    public BusyIndicator() {
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        MouseInputListener blockMouseEvents = new MouseInputAdapter() {
        };
        addMouseMotionListener(blockMouseEvents);
        addMouseListener(blockMouseEvents);
        InputVerifier retainFocusWhileVisible = new InputVerifier() {

            public boolean verify(JComponent c) {
                return !c.isVisible();
            }
        };
        setInputVerifier(retainFocusWhileVisible);
    }

    public void actionPerformed(ActionEvent ignored) {
        frame += 1;
        repaint();
    }

    void start() {
        setVisible(true);
        requestFocusInWindow();
        timer.start();
    }

    void stop() {
        setVisible(false);
        timer.stop();
    }

    @Override
    protected void paintComponent(Graphics g) {
        RoundRectangle2D bar = new RoundRectangle2D.Float(
                innerRadius, -barWidth / 2, outerRadius, barWidth, barWidth, barWidth);
        // x,         y,          width,       height,   arc width,arc height
        double angle = Math.PI * 2.0 / (double) nBars; // between bars
        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(getWidth() / 2, getHeight() / 2);
        g2d.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        for (int i = 0; i < nBars; i++) {
            // compute bar i's color based on the frame index
            Color barColor = new Color((int) barGray, (int) barGray, (int) barGray);
            if (frame != -1) {
                for (int t = 0; t < trailLength; t++) {
                    if (i == ((frame - t + nBars) % nBars)) {
                        float tlf = (float) trailLength;
                        float pct = 1.0f - ((tlf - t) / tlf);
                        int gray = (int) ((barGray - (pct * barGray)) + 0.5f);
                        barColor = new Color(gray, gray, gray);
                    }
                }
            }
            // draw the bar
            g2d.setColor(barColor);
            g2d.fill(bar);
            g2d.rotate(angle);
        }
    }
}
